import {
  Shader,
  ShaderData,
  ShaderProperty,
  ShaderPool,
  ShaderProgram,
  ShaderProgramPool,
  ShaderMacro,
  ShaderMacroCollection,
  ShaderDataGroup,
  ShaderLib
} from "@nirvana/shaders";
import { Color, Vector3 } from "@nirvana/math";

import { WebGLCanvas } from "@nirvana/canvas";
import { Data, Mesh, DataElement, Geometry, SimpleMaterial, Camera, ShaderMaterial, TextureUtil } from "@nirvana/core";

// 使用使用 Canvas
let canvas = document.getElementById("engine-nirvana") as HTMLCanvasElement;
const webCanvas = new WebGLCanvas(canvas, { isWebGL2: false });
const engine = webCanvas.engine;
const gl = engine.gl;

const pData = new Float32Array([
  -0.5, -0.5,  -0.5,
    -0.5,  0.5,  -0.5,
     0.5, -0.5,  -0.5,
    -0.5,  0.5,  -0.5,
     0.5,  0.5,  -0.5,
     0.5, -0.5,  -0.5,

    -0.5, -0.5,   0.5,
     0.5, -0.5,   0.5,
    -0.5,  0.5,   0.5,
    -0.5,  0.5,   0.5,
     0.5, -0.5,   0.5,
     0.5,  0.5,   0.5,

    -0.5,   0.5, -0.5,
    -0.5,   0.5,  0.5,
     0.5,   0.5, -0.5,
    -0.5,   0.5,  0.5,
     0.5,   0.5,  0.5,
     0.5,   0.5, -0.5,

    -0.5,  -0.5, -0.5,
     0.5,  -0.5, -0.5,
    -0.5,  -0.5,  0.5,
    -0.5,  -0.5,  0.5,
     0.5,  -0.5, -0.5,
     0.5,  -0.5,  0.5,

    -0.5,  -0.5, -0.5,
    -0.5,  -0.5,  0.5,
    -0.5,   0.5, -0.5,
    -0.5,  -0.5,  0.5,
    -0.5,   0.5,  0.5,
    -0.5,   0.5, -0.5,

     0.5,  -0.5, -0.5,
     0.5,   0.5, -0.5,
     0.5,  -0.5,  0.5,
     0.5,  -0.5,  0.5,
     0.5,   0.5, -0.5,
     0.5,   0.5,  0.5, 
]);
// const cData = new Float32Array([
//   5,3,7, 5,3,7, 5,3,7, 5,3,7,
//   1,1,3, 1,1,3, 1,1,3, 1,1,3,
//   0,0,1, 0,0,1, 0,0,1, 0,0,1,
//   1,0,0, 1,0,0, 1,0,0, 1,0,0,
//   1,1,0, 1,1,0, 1,1,0, 1,1,0,
//   0,1,0, 0,1,0, 0,1,0, 0,1,0
// ]);
// const iData = new Uint16Array([
//   0,1,2, 0,2,3, 4,5,6, 4,6,7,
//   8,9,10, 8,10,11, 12,13,14, 12,14,15,
//   16,17,18, 16,18,19, 20,21,22, 20,22,23
// ]);

const gem = new Geometry();
gem.addData(new Data(pData, [new DataElement("POSITION", 3)]));
// gem.addData(new Data(cData, [new DataElement("COLOR", 3, gl.FLOAT, false, 0, 0)]));
// gem.addData(new Data(iData));

const vs = `
attribute vec4 a_position;

uniform mat4 u_projMat;
uniform mat4 u_viewMat;
uniform mat4 u_modelMat;
uniform mat4 u_normalMat;

varying vec3 v_normal;

void main() {
  // Multiply the position by the matrix.
  gl_Position = u_projMat * u_viewMat * u_modelMat *  a_position;

  // Pass a normal. Since the positions
  // centered around the origin we can just 
  // pass the position
  v_normal = normalize(a_position.xyz);
}
`;
const fs = `
precision mediump float;

// Passed in from the vertex shader.
varying vec3 v_normal;

// The texture.
uniform samplerCube u_texture;

void main() {
   gl_FragColor = textureCube(u_texture, normalize(v_normal));
}
`;

const shader = Shader.create("d", vs, fs);
const mtl = new ShaderMaterial("", shader);
const entity = new Mesh(gem, mtl);

const fbi = TextureUtil.createFramebufferInfo(
  engine.gl,
  // undefined,
  [
    {
      format: gl.RGBA,
      // format: gl.RGBA4,
      target: gl.TEXTURE_CUBE_MAP
      // src: "/dev-static/textures/a.png"
    },
    // {
    //   format: gl.RGBA,
    //   target: gl.TEXTURE_CUBE_MAP,
    //   src: "/dev-static/textures/a.png"
    // },
    // {
    //   format: gl.RGBA,
    //   target: gl.TEXTURE_CUBE_MAP,
    //   src: "/dev-static/textures/a.png"
    // },
    // {
    //   format: gl.RGBA,
    //   target: gl.TEXTURE_CUBE_MAP,
    //   src: "/dev-static/textures/a.png"
    // },
    // { format: gl.RGBA, target: gl.TEXTURE_2D},
    // { format: gl.DEPTH_COMPONENT },
    // { format: gl.DEPTH_COMPONENT },
  ],
  256,
  256
);

const shaderData = mtl.shaderData;
shaderData.setTexture("u_texture", {
  // _glTexture: fTexture,
  _glTexture: TextureUtil.createTexture(
    engine.gl,
    {
      target: gl.TEXTURE_CUBE_MAP,
      // src: [
      //   "/dev-static/textures/yokohama/posx.jpg",
      //   "/dev-static/textures/yokohama/negx.jpg",
      //   "/dev-static/textures/yokohama/posy.jpg",
      //   "/dev-static/textures/yokohama/negy.jpg",
      //   "/dev-static/textures/yokohama/posz.jpg",
      //   "/dev-static/textures/yokohama/negz.jpg"
      // ]
      src: "/dev-static/textures/a.png",
      size: 4,
      slices: [1, 0, 0, 1, 1, 1, 2, 1, 3, 1, 1, 2],
      cubeFaceOrder: [
        gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
        gl.TEXTURE_CUBE_MAP_POSITIVE_X,
        gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
        gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
        gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,
        gl.TEXTURE_CUBE_MAP_NEGATIVE_Y
      ]
    },
    null
  ),
  _target: gl.TEXTURE_CUBE_MAP
});
// shaderData.setTexture("u_texture", {
//   _glTexture: fbi.attachments[0],
//   _target: gl.TEXTURE_CUBE_MAP
// });

// enable necessary extensions

const scene = engine.sceneManager.createScene("root");
scene.addEntity(entity);
const camera = new Camera(engine);
scene.addCamera(camera);
camera.transform.setPosition(new Vector3(0, 0, 10));

engine.update = () => {
  // for (let i = 0; i < 4; i++) {
  //   const t = target[i];
  //   gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
  //   gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, t, fTexture, 0);

  //   // フレームバッファを初期化
  // gl.clearColor(0.0, 1.0, 0.0, 1.0);
  // gl.clearDepth(1.0);
  // gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  //   gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  // }
  // [
  //   gl.TEXTURE_CUBE_MAP_POSITIVE_X,
  //   gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
  //   gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
  //   gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
  //   gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
  //   gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
  // ].map((someTarget, i) => {
    TextureUtil.bindFramebufferInfo(gl, fbi);

    // gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, someTarget, fbi.attachments[0], 0);
    // gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0+i, gl.TEXTURE_CUBE_MAP_POSITIVE_X, fbi.attachments[0], 0);
    // gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + 1, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, fbi.attachments[0], 0);
    // gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + 2, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, fbi.attachments[0], 0);
    // gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + 3, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, fbi.attachments[0], 0);
    // gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + 4, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, fbi.attachments[0], 0);
    // gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + 5, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, fbi.attachments[0], 0);
    gl.clearColor(0.0, 1.0, 0.0, 1.0);
    gl.clearDepth(1.0);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    TextureUtil.bindFramebufferInfo(gl, null);
    // gl.framebufferTexture2D(target, attachmentPoint, someTarget, attachment, attachmentOptions.level || 0);
  // });

  //
  // フレームバッファにテクスチャを関連付ける
  // gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, target[i], fTexture, 0);
  // if(++i > 3) i=0;
  // // console.log("--");
  // gl.clearColor(0.0, 0.0, 0.0, 1.0);
  // // 用上面指定的颜色清除缓冲区
  // gl.clear(gl.COLOR_BUFFER_BIT);
  // entity.transform.translate(new Vector3(0, 0.01, 0));
  // entity1.transform.translate(new Vector3(0.01, 0.02, 0));
  // entity2.transform.translate(new Vector3(-0.01, 0.02, 0));
  // entity3.transform.translate(new Vector3(0.01, -0.02, 0));
  // let rand = 5 * Math.random();
  // entity.transform.rotate(new Vector3(0, 0, rand));
  entity.transform.rotate(new Vector3(0.1, 0.7, 0.9));
  // entity.transform.rotate(new Vector3(0, 0, 2));
  // entity2.transform.rotate(new Vector3(0, 0, 4));
  // entity3.transform.rotate(new Vector3(0, 0, 6));
  // entity.transform.scale(new Vector3(rand, rand, rand));

  // TextureUtil.bindFramebufferInfo(engine.gl, fbi);
  // shaderData.setTexture("u_texture", {
  //   _glTexture: fTexture,
  //   _target: gl.TEXTURE_CUBE_MAP
  // });

  shaderData.setTexture("u_texture", {
    _glTexture: fbi.attachments[0],
    _target: gl.TEXTURE_CUBE_MAP
  });
};
